在上一篇 Day 20 我們介紹了 React Router 的基本概念以及 React Router Dom 的三大類別元件的其中一個 Routes 的部分。那今天就要接續為大家來介紹剩下的兩個類別:Route Matchers 和 Navigation 。
包含了
<Route>
和<Switch>
兩個 Route Matching 元件,透過兩個元件的搭配能夠將路徑指向對應的元件並判別當中是否有符合對應路徑的元件。
而這個類別內也包含兩種元件,那這兩個元件是代表什麼意思?又分別有什麼功能?
<Route>
:用來指定元件所要對應的路徑。<Switch>
:通常會使用在 <Route>
的父層並在遍歷所有的子元件 <Route>
之後,將其中第一個符合的對應路徑的元件渲染出來。下面我們直接看官方文件的範例該怎麼使用?
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
function App() {
return (
<div>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact/:id">
<Contact />
</Route>
<Route path="/contact">
<AllContacts />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
);
}
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
上面的範例中,我們使用了 <Route>
元件並在該元件內部給於一個 path
屬性來指定路徑的 url ,而在 <Route>
的內層再引入我們要渲染的元件。這樣當路徑指定到對應的 url 時,畫面上就會顯示該路徑下的那個元件了。
而將 <Switch>
加入到 <Route>
的父層之後, <Swith>
元件會搜尋其所包覆的所有 <Route>
中的 path
是否有符合對應的 url ? 若確認有符合的話,才會將第一個有符合的元件渲染出來。
不過這邊關於 <Route>
和 <Switch>
分別都有要注意的地方:
<Switch>
的特點剛剛的說明以及範例中我們都知道了 <Switch>
如果使用在 <Route>
的父層時它會遍歷所有 <Route>
元件中的 url ,只要有符合路徑的第一個 <Route>
就會渲染出來。但是這邊要特別注意,在 Route Matching 元件中對比符合路徑的規則是從 path
最左邊開始進行路徑對比的。
所以大家有發現嗎?在上面的範例中,我們將包覆 <Home />
這個元件的 <Route>
路徑指定為 path="/"
並將它放在所有路由的最下方,原因就是出在這邊。
如果我們將 <Home />
這個元件擺在所有的 <Route>
上方的話,這樣 path
的 url 無論怎麼改變都會符合到 <Home />
的路徑: path="/"
(因為每個 path
都包含了 /
),這樣也會導致即便切換了 url 之後,畫面還是只會顯示 <Home />
這個元件的 bug 產生。
那除了將該元件移動到所有 <Route>
最下方之外,還有別的解決辦法嗎?答案是有的,下面我們就要來看 <Route>
的其他屬性怎麼幫助我們解決這個狀況?
<Route>
的屬性在 <Route>
這個 Route Matching 元件中其實具備了三個屬性提供你做設定:
path
: 設定該元件的路徑 url 。component
:設定該路由要渲染出的元件。exact
:加入此屬性後,當路徑完全等於 path
的 url 時才會確實渲染元件。了解了 <Route>
這三個屬性之後,我們試著將上面的範例用這些屬性來改寫一下:
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
function App() {
return (
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={AllContacts} />
<Route path="/contact/:id" component={Contact} />
</Switch>
</div>
);
}
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
改寫之後可以看到,透過 <Route>
這些屬性我們可以把路由管理整理得更清楚明瞭!而且只要修正 <Route>
的屬性就可以調整我們所需的東西,讓我們在開發的過程也更好做管理。
包含了
<Link>
、<NavLink>
和<Redirect>
三個 Route Changers 元件,分別有各自的功能:
<Link>
<Link to="/">Home</Link>
/* 渲染的結果會為:<a href="/">Home</a> */
<Link>
元件會將你在 to
參數上所設定的路徑轉換成 <a>
標籤的連結,讓你可以把設定好的路由綁定到你的內容上。
備註:這邊關於 <Link>
的詳細介紹可以參考 Andy 大大的:【React.js入門 - 28】 我要更多更多的分頁 - react-router-dom (下) ,裡面有更清楚的說明!
<NavLink>
<NavLink to="/react" activeClassName="hurray">
React
</NavLink>
<NavLink>
也是採用 <Link>
元件的概念,但是它可以額外設定一個屬性 activeClassName
:當目前的 url 的路徑確實吻合 <NavLink>
裡面 to
屬性所指定的路徑時,這個指定的 className
才會被觸發。
所以針對上面的程式碼,對於它渲染的結果我們可以這樣解讀:
/* 當路徑的 URL 完全符合 /react 時,渲染以下的內容 */
<a href="/react" className="hurray">React</a>
/* 當路徑的 URL 不符合 /react 時,渲染以下的內容 */
<a href="/react">React</a>
<Redirect>
<Redirect to="/login" />
<Redirect>
可以將路由重新連結到指定的路徑,大部分是用在畫面要重新導向或是所有的 <Route>
都無法正確的渲染對應的元件時才會使用。且通常 <Redirect>
都會加入到路由管理的最下方,如下方範例:
function App() {
return (
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={AllContacts} />
<Redirect to="/" />
</Switch>
</div>
);
}
關於 React.js 路由的管理和 React Router Dom 的介紹就到這邊告一個段落了。
意外發現 React Router 跟 Vue Router 的功能比較起來好像大同小異(不過也有可能是我還沒真的用 React.js 開發過),但是 React Router 的元件和方法的命名真的相對來說更直觀更貼切,比較容易記得起來。
明天就要進入 React.js 中的狀態管理: Redux 了。聽說這是大部分初學者剛接觸 React.js 時比較難入手的地方,所以有點緊張 XD
那如果有任何問題一樣非常非常歡迎提出和指教喔!
我們下篇見ʘ‿ʘ